#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/HttpUtil.h>
#include <workflow/Workflow.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <vector>
#include <iostream>

using std::cout;
using std::cerr;
using std::string;
using std::vector;

struct SeriesContext {
    string url;
    size_t size;
};
static WFFacilities::WaitGroup waitGroup(1);

void handler(int) {
    cout << "done!\n";
    waitGroup.done();
}

void httpCallback(WFHttpTask *httpTask) {
    protocol::HttpResponse *resp = httpTask->get_resp();
    const void *body;
    size_t size;
    resp->get_parsed_body(&body, &size);
    SeriesContext *context = static_cast<SeriesContext *>(series_of(httpTask)->get_context());
    context->size = size;
    cout << "http callback url = " << context->url << " size = " << context->size << "\n";
}

void parallelCallback(const ParallelWork *parallelWork) {
    string cururl = "";
    size_t cursize = 0;
    for (int i = 0; i < parallelWork->size(); ++i) {
        SeriesContext *context = static_cast<SeriesContext *>(parallelWork->series_at(i)->get_context());
        if (context->size > cursize) {
            cururl = context->url;
            cursize = context->size;
        }
        delete context;
    }
    cout << "biggest url = " << cururl << " size = " << cursize << "\n";

    SeriesWork *bigSeries = series_of(parallelWork);

    /* 把最长的存到redis中 */
    WFRedisTask *redisTask = WFTaskFactory::create_redis_task("*", 10, nullptr);
    redisTask->get_req()->set_request("SET", {cururl, std::to_string(cursize)});
    bigSeries->push_back(redisTask);
}

int main() {
    signal(SIGINT, handler);

    // 1 创建一个空的并行任务
    ParallelWork *parallelWork = Workflow::create_parallel_work(nullptr);

    vector<string> urls{
        "http://www.taobao.com",
        "http://www.jd.com",
        "http://www.baidu.com"
    };

    for (int i = 0; i < 3; ++i) {
        // 2.1 创建http任务
        WFHttpTask *httpTask = WFTaskFactory::create_http_task(urls[i], 10, 10, httpCallback);

        // 2.2 根据任务创建序列
        SeriesWork *series = Workflow::create_series_work(httpTask, nullptr);

        // 每个序列有一个context
        SeriesContext *context = new SeriesContext;
        context->url = urls[i];
        series->set_context(context);

        // 3 将序列加入到并行任务中
        parallelWork->add_series(series);
    }

    parallelWork->set_callback(parallelCallback);

    parallelWork->start();
    waitGroup.wait();

    cout << "finished!\n";
    return 0;
}